import type React from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTheme } from '../../theme'
import styles from './Slider.module.less'

export interface SliderProps {
  min?: number
  max?: number
  value?: number
  defaultValue?: number
  step?: number
  disabled?: boolean
  onChange?: (value: number) => void
  onAfterChange?: (value: number) => void
  showTooltip?: boolean
  glow?: boolean
  className?: string
}

const Slider: React.FC<SliderProps> = ({
  min = 0,
  max = 100,
  value: controlledValue,
  defaultValue = 0,
  step = 1,
  disabled = false,
  onChange,
  onAfterChange,
  showTooltip = true,
  glow = false,
  className,
}) => {
  const { theme, themeName } = useTheme()
  const [value, setValue] = useState(controlledValue ?? defaultValue)
  const [isDragging, setIsDragging] = useState(false)
  const [showTooltipVisible, setShowTooltipVisible] = useState(false)
  const sliderRef = useRef<HTMLDivElement>(null)
  const trackRef = useRef<HTMLDivElement>(null)

  const isControlled = controlledValue !== undefined
  const currentValue = isControlled ? controlledValue : value

  const percentage = ((currentValue - min) / (max - min)) * 100

  const updateValue = useCallback(
    (clientX: number) => {
      if (!trackRef.current || disabled) return

      const rect = trackRef.current.getBoundingClientRect()
      const percentage = Math.max(0, Math.min(100, ((clientX - rect.left) / rect.width) * 100))
      const rawValue = (percentage / 100) * (max - min) + min
      const steppedValue = Math.round(rawValue / step) * step
      const clampedValue = Math.max(min, Math.min(max, steppedValue))

      if (!isControlled) {
        setValue(clampedValue)
      }
      onChange?.(clampedValue)
    },
    [min, max, step, disabled, isControlled, onChange]
  )

  const handleMouseDown = (e: React.MouseEvent) => {
    if (disabled) return
    setIsDragging(true)
    setShowTooltipVisible(true)
    updateValue(e.clientX)
  }

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (isDragging) {
        updateValue(e.clientX)
      }
    },
    [isDragging, updateValue]
  )

  const handleMouseUp = useCallback(() => {
    if (isDragging) {
      setIsDragging(false)
      setShowTooltipVisible(false)
      onAfterChange?.(currentValue)
    }
  }, [isDragging, currentValue, onAfterChange])

  useEffect(() => {
    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('mouseup', handleMouseUp)
      return () => {
        document.removeEventListener('mousemove', handleMouseMove)
        document.removeEventListener('mouseup', handleMouseUp)
      }
    }
  }, [isDragging, handleMouseMove, handleMouseUp])

  const classNames = [
    styles.slider,
    styles[`theme-${themeName}`],
    disabled && styles.disabled,
    glow && styles.glow,
    className,
  ]
    .filter(Boolean)
    .join(' ')

  const sliderStyle = {
    '--theme-primary-gradient': theme.colors.primary.gradient,
    '--theme-primary-main': theme.colors.primary.main,
    '--theme-primary-light': theme.colors.primary.light,
    '--theme-primary-shadow': theme.colors.shadow.primary,
    '--theme-glow-gradient': `linear-gradient(45deg, ${theme.colors.primary.light}, ${theme.colors.primary.main}, ${theme.colors.primary.dark}, ${theme.colors.primary.light})`,
  } as React.CSSProperties

  return (
    <div ref={sliderRef} className={classNames} style={sliderStyle}>
      <div className={styles.track}>
        <div ref={trackRef} className={styles.trackClickable} onMouseDown={handleMouseDown}>
          <div className={styles.trackBg} />
          <div className={styles.trackFilled} style={{ width: `${percentage}%` }} />
        </div>
        <div
          className={styles.thumb}
          style={{ left: `${percentage}%` }}
          onMouseDown={handleMouseDown}
        />
        {showTooltip && (showTooltipVisible || isDragging) && (
          <div className={styles.tooltip} style={{ left: `${percentage}%` }}>
            {currentValue}
          </div>
        )}
      </div>
    </div>
  )
}

export default Slider
